package com.twt.recruit.controller;


import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.twt.recruit.entity.*;
import com.twt.recruit.entity.vo.CategoryParam1;
import com.twt.recruit.mapper.*;
import com.twt.recruit.service.*;
import com.twt.recruit.utils.JwtTokenUtils;
import com.twt.recruit.utils.response.CommonEnum;
import com.twt.recruit.utils.response.ResultBody;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.util.*;

@RestController
@RequestMapping("/v1")
public class ProjectController {

    private final static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    ProjectMapper projectMapper;

    @Resource
    GroupMapper groupMapper;

    @Resource
    ProjectGroupMapper projectGroupMapper;

    @Resource
    QuestionMapper questionMapper;

    @Resource
    ApplicationMapper applicationMapper;

    @Resource
    ClubMapper clubMapper;

    @Resource
    CategoryMapper categoryMapper;

    @Resource
    AnswerService answerService;

    @Resource
    ApplicationService applicationService;

    @Resource
    CategoryService categoryService;

    @Resource
    MessageService messageService;

    @Resource
    ProjectService projectService;

    @Resource
    QuestionService questionService;

    @Resource
    TimeService timeService;


    @PostMapping("/child/project")
    @Operation(summary = "新建项目")
    public ResultBody addProject(@RequestParam String title,
                                 @RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token,
                                 @Parameter(description = "项目下设组别") @RequestParam List<String> groups,
                                 @Parameter(description = "多张封面图") String covers,
                                 @Parameter(description = "多张背景图") String backgrounds,
                                 @Parameter(description = "0:院级;1:校级") @RequestParam Integer scale,
                                 @RequestParam String questions,
                                 @RequestParam String brief,
                                 @RequestParam String rules,
                                 @RequestParam String contact,
                                 @Parameter(description = "标题色号,hex") @RequestParam(defaultValue = "#FFFFFFFF") String titleColor,
                                 @Parameter(description = "背景颜色,hex") @RequestParam(defaultValue = "#00A1E9FF") String backColor,
                                 @RequestParam(defaultValue = "0") String pageMethod,
                                 @RequestParam(defaultValue = "0") String circleMethod,
                                 @RequestParam(defaultValue = "1") String slideLock,
                                 @Parameter(description = "2002-04-11") @RequestPart String endTime){
        try {
            Integer clubId = JwtTokenUtils.getClubHttp(token);

            //项目基本信息
            //endTimes 表示接收问卷的截至时间
            //startTimes 表示面试开始时间
            //理论上 startTimes 应晚于 endTimes
            String endTimes = endTime+" 23:59:59";
            String startTimes = endTime+" 00:00:00";

            Project project = new Project();
            project.setTitle(title);
            project.setScale(scale);
            project.setBrief(brief);
            project.setClubId(clubId);
            project.setCover(covers);
            project.setBackground(backgrounds);
            project.setRules(rules);
            project.setContact(contact);
            project.setStartTime(Timestamp.valueOf(startTimes));
            project.setEndTime(Timestamp.valueOf(endTimes));
            project.setTitleColor(titleColor);
            project.setBackColor(backColor);
            project.setCircleMethod(circleMethod);
            project.setPageMethod(pageMethod);
            project.setSlideLock(slideLock);
            projectMapper.insert(project);

            Integer projectId = project.getProjectId();

            //先插入组别
            List<GroupInfo> groupInfoList = new ArrayList<>();
            Set<String> groupSet = new HashSet<>(groups);
            for (String groupName : groupSet){
                GroupInfo groupInfo = new GroupInfo();
                groupInfo.setGroupName(groupName);
                groupInfo.setClubId(clubId);

                LambdaQueryWrapper<GroupInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(GroupInfo::getClubId, clubId);
                queryWrapper.eq(GroupInfo::getGroupName, groupName);
                List<GroupInfo> groupInfos = groupMapper.selectList(queryWrapper);
                if (groupInfos.isEmpty()){
                    groupMapper.insert(groupInfo);
                }else {
                    groupInfo.setGroupId(groupInfos.get(0).getGroupId());
                }
                groupInfoList.add(groupInfo);
            }

            for (int i = 0; i < groupInfoList.size();i++){
                GroupInfo groupInfo = groupInfoList.get(i);
                //初始化分组
                projectGroupMapper.insert(new ProjectGroup(null, groupInfo.getGroupId(), projectId,i+1));
            }



            //解析对应组别问题
            JSONArray groupQuestions = JSONUtil.parseArray(questions);
            groupQuestions.forEach(d->{
                questionMapper.addPrimeQuestions(projectId, d.toString());
                JSONObject questionDetail = JSONUtil.parseObj(d);
                List<String> groupNames = questionDetail.getBeanList("groups", String.class);
                questionDetail.remove("groups");
                for (String groupName : groupNames) {
                    Integer groupId = groupMapper.getGroupId(clubId, groupName);
                    Question question = new Question();
                    question.setProjectId(projectId);
                    question.setQuestionContent(questionDetail.toString());
                    question.setGroupId(groupId);
                    questionMapper.insert(question);
                }
            });
            return ResultBody.success(projectService.getSingleProject(projectId));


        }catch (Exception e){
            logger.error("新建项目失败", e);
            return ResultBody.error("新建项目失败");
        }

    }

    @PostMapping("/child/project/status")
    @Operation(summary = "修改项目状态")
    public ResultBody updateProjectStatus(@RequestParam Integer projectId,
                                          @RequestParam Integer status,
                                          @RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token){

        if (!projectService.isClubProject(projectId, JwtTokenUtils.getClubHttp(token))){
            return ResultBody.error(CommonEnum.PROJECT_VIRES);
        }
        LambdaUpdateWrapper<Project> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Project::getProjectId, projectId);
        updateWrapper.set(Project::getStatus, status);
        return ResultBody.success(projectMapper.update(updateWrapper));
    }


    @PostMapping("/child/project/delete")
    @Operation(summary = "删除项目")
    //需删除所有包含字段project_id的表，以及因此受影响的其他表
    //直接包含project_id的表有：answer,application,a_i,category,message,project,p_g,question,q_o,time,t_h
    //间接受影响的表有：a_o_p(answer_id),a_c(application_id),c_i(category_id),g_i()
    public ResultBody deleteProject(@RequestParam Integer projectId,
                                    @RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token){
        if (!projectService.isClubProject(projectId, JwtTokenUtils.getClubHttp(token))){
            return ResultBody.error(CommonEnum.PROJECT_VIRES);
        }

        //删除answer相关
        List<Answer> answerList = answerService.getAnswerByProjectId(projectId);
        List<Integer> answerIdList = new ArrayList<>();
        for (Answer answer : answerList){
            answerIdList.add(answer.getAnswerId());
        }

        answerService.delAnswerByProjectId(projectId);
        if (!answerIdList.isEmpty()){
            answerService.delAnswerOptionByAnswerId(answerIdList);
        }

        //删除appliction相关
        List<Integer> applicationIdList = applicationMapper.listApplicationIdsByProjectId(projectId);
        applicationService.delApplicationByProjectId(projectId);
        applicationService.delApplicationInfoByProjectId(projectId);
        if (!applicationIdList.isEmpty()){
            applicationService.delApplicationCommentByApplicationId(applicationIdList);
        }

        //删除category相关
        List<CategoryParam1> categoryParamList = categoryMapper.getCategoryIdsByProjectId(projectId);
        List<Integer> categoryIdList = new ArrayList<>();
        for (CategoryParam1 categoryParam1 : categoryParamList){
            categoryIdList.add(categoryParam1.getCategoryId());
        }
        categoryService.delCategoryByProjectId(projectId);
        if (!categoryIdList.isEmpty()){
            categoryService.delCategoryInfoByCategoryId(categoryIdList);
        }

        //删除group相关
        List<Integer> groupIdList = groupMapper.getGroupIdByProjectId(projectId);
        groupMapper.delProjectGroupByProjectId(projectId);
        groupMapper.delGroupByGroupId(groupIdList);

        //删除message相关
        messageService.delMessageByProjectId(projectId);

        //删除project相关
        projectService.delProjectByProjectId(projectId);
        projectService.delProjectGroupByProjectId(projectId);

        //删除question相关
        questionService.delQuestionProjectId(projectId);
        questionService.delQuestionOptionProjectId(projectId);
        questionService.delPrimeQuestionByProjectId(projectId);

        //删除time相关
        timeService.delTimeProjectId(projectId);
        timeService.delTimeHandProjectId(projectId);

        return ResultBody.success();
    }

    @GetMapping("/user/project")
    @Operation(summary = "获取项目信息")
    public ResultBody getProject(@RequestParam Integer projectId){
        try {
            if (projectMapper.selectById(projectId)==null){
                return ResultBody.error(CommonEnum.PROJECT_NOT_FOUND);
            }
            return ResultBody.success(projectService.getSingleProject(projectId));
        }catch (Exception e){
            logger.error("获取项目信息失败", e);
            return ResultBody.error("获取项目信息失败");
        }
    }

    @Operation(summary = "生成二维码")
    @GetMapping("/user/project/qr")
    public void getProjectQr(@RequestParam("url") String url,
                             HttpServletResponse response){
        try {
            OutputStream os = response.getOutputStream();
            QrConfig config = new QrConfig(300, 300);
            config.setMargin(3);
            QrCodeUtil.generate(url, config, "svg",os);
            os.close();
        }catch (Exception e){
            logger.error("fail generate QR", e);
        }
    }

//    @PostMapping("/child/project/update")
//    @Operation(summary = "修改项目", description = "参数参考新建项目接口")
//    public ResultBody updateProject(@RequestParam Integer projectId,
//                                    @RequestParam String title,
//                                    @RequestParam String covers,
//                                    @RequestParam String backgrounds,
//                                    @RequestParam String brief,
//                                    @RequestParam String contact,
//                                    @RequestParam String endTime,
//                                    @RequestParam String titleColor,
//                                    @RequestParam String backColor,
//                                    @RequestParam String pageMethod,
//                                    @RequestParam String circleMethod,
//                                    @RequestParam String slideLock,
//                                    @RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token) {
//        try {
//            if (!projectService.isClubProject(projectId, JwtTokenUtils.getClubHttp(token))){
//                return ResultBody.error(CommonEnum.PROJECT_VIRES);
//            }
//
//            endTime  = endTime+" 23:59:59";
//            Timestamp ddl = Timestamp.valueOf(endTime);
//            Project project = projectMapper.selectById(projectId);
//            project.setTitle(title);
//            project.setCover(covers);
//            project.setBrief(brief);
//            project.setContact(contact);
//            project.setTitleColor(titleColor);
//            project.setBackColor(backColor);
//            project.setBackground(backgrounds);
//            project.setPageMethod(pageMethod);
//            project.setCircleMethod(circleMethod);
//            project.setSlideLock(slideLock);
//            project.setEndTime(ddl);
//            projectMapper.updateById(project);
//            return ResultBody.success("修改成功");
//
//        }catch (Exception e){
//            logger.error("修改项目失败", e);
//            return ResultBody.error("修改项目失败");
//        }
//
//    }


    @PostMapping("/child/project/update/all")
    @Operation(summary = "修改项目(包括问题,组别，相当于新建一个项目)", description = "参数参考新建项目接口")
    public ResultBody updateAllProject(@RequestParam Integer projectId,
                                       @RequestParam String title,
                                       @RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token,
                                       @Parameter(description = "项目下设组别") @RequestParam List<String> groups,
                                       @Parameter(description = "多张封面图") String covers,
                                       @Parameter(description = "多张背景图") String backgrounds,
                                       @Parameter(description = "0:院级;1:校级") @RequestParam Integer scale,
                                       @RequestParam String questions,
                                       @RequestParam String brief,
                                       @RequestParam String rules,
                                       @RequestParam String contact,
                                       @Parameter(description = "标题色号,hex") @RequestParam(defaultValue = "#FFFFFFFF") String titleColor,
                                       @Parameter(description = "背景颜色,hex") @RequestParam(defaultValue = "#00A1E9FF") String backColor,
                                       @RequestParam(defaultValue = "0") String pageMethod,
                                       @RequestParam(defaultValue = "0") String circleMethod,
                                       @RequestParam(defaultValue = "1") String slideLock,
                                       @Parameter(description = "2002-04-11") @RequestPart String endTime){
        try {

//            //先删除原来的分组
//            List<Integer> primeGroups = groupMapper.getGroupIdByProjectId(projectId);
//            groupMapper.delProjectGroupByProjectId(projectId);
//            groupMapper.delGroupByGroupId(primeGroups);

            Integer clubId = JwtTokenUtils.getClubHttp(token);

            //项目基本信息
            //endTimes 表示接收问卷的截至时间
            //startTimes 表示面试开始时间
            //理论上 startTimes 应晚于 endTimes
            String endTimes = endTime+" 23:59:59";
            String startTimes = endTime+" 00:00:00";

            Project project = projectMapper.selectById(projectId);
            String primeRules = project.getRules();

            project.setTitle(title);
            project.setScale(scale);
            project.setBrief(brief);
            project.setClubId(clubId);
            project.setCover(covers);
            project.setBackground(backgrounds);
            project.setRules(rules);
            project.setContact(contact);
            project.setStartTime(Timestamp.valueOf(startTimes));
            project.setEndTime(Timestamp.valueOf(endTimes));
            project.setTitleColor(titleColor);
            project.setBackColor(backColor);
            project.setCircleMethod(circleMethod);
            project.setPageMethod(pageMethod);
            project.setSlideLock(slideLock);
            projectService.updateById(project);
            //projectMapper.insert(project);

            //对于组别和问题，把原本的全部删掉，再插入新的，实现"更新"，同时还需要删除对应的application和category

            //修改组别
            List<String> primeGroups = projectGroupMapper.getGroupsByProjectId(projectId);
            List<String> primeGroups1 = primeGroups;
            List<String> newGroups = groups;

            Collections.sort(primeGroups);
            Collections.sort(primeGroups1);
            Collections.sort(groups);
            Collections.sort(newGroups);

            for (int i = 0; i < newGroups.size();) {
                String group = newGroups.get(i);
                if (primeGroups1.contains(group)) {
                    primeGroups1.remove(group);
                    newGroups.remove(group);
                } else {
                    i++;
                }
            }

            //删除现在不存在的组
            for (String group : primeGroups1) {
                Integer groupId = groupMapper.getGroupId(clubId, group);
                projectGroupMapper.delOneProjectGroup(projectId, groupId);
            }

            //增加原来不存在的组
            List<GroupInfo> groupInfoList = new ArrayList<>();
            Set<String> groupSet = new HashSet<>(newGroups);
            for (String groupName : groupSet){
                GroupInfo groupInfo = new GroupInfo();
                groupInfo.setGroupName(groupName);
                groupInfo.setClubId(clubId);

                LambdaQueryWrapper<GroupInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(GroupInfo::getClubId, clubId);
                queryWrapper.eq(GroupInfo::getGroupName, groupName);
                List<GroupInfo> groupInfos = groupMapper.selectList(queryWrapper);
                if (groupInfos.isEmpty()){
                    groupMapper.insert(groupInfo);
                }else {
                    groupInfo.setGroupId(groupInfos.get(0).getGroupId());
                }
                groupInfoList.add(groupInfo);
            }

            for (int i = 0; i < groupInfoList.size();i++){
                GroupInfo groupInfo = groupInfoList.get(i);
                //初始化分组
                projectGroupMapper.insert(new ProjectGroup(null, groupInfo.getGroupId(), projectId,i+1));
            }


            List<String> primeQuestions = questionMapper.getPrimeQuestions(projectId);

            //先删除原来的问题以及对应的回答
            questionMapper.delQuestionProjectId(projectId);
            questionMapper.delQuestionOptionProjectId(projectId);
            questionService.delPrimeQuestionByProjectId(projectId);

            List<Answer> answerList = answerService.getAnswerByProjectId(projectId);
            List<Integer> answerIdList = new ArrayList<>();
            for (Answer answer : answerList){
                answerIdList.add(answer.getAnswerId());
            }
            answerService.delAnswerByProjectId(projectId);
            if (!answerIdList.isEmpty()) {
                answerService.delAnswerOptionByAnswerId(answerIdList);
            }


            //解析对应组别问题
            List<String> newQuestions = new ArrayList<>();

            JSONArray groupQuestions = JSONUtil.parseArray(questions);
            groupQuestions.forEach(d->{
                newQuestions.add(d.toString());
                questionMapper.addPrimeQuestions(projectId, d.toString());
                JSONObject questionDetail = JSONUtil.parseObj(d);
                List<String> groupNames = questionDetail.getBeanList("groups", String.class);
                questionDetail.remove("groups");
                for (String groupName : groupNames) {
                    Integer groupId = groupMapper.getGroupId(clubId, groupName);
                    Question question = new Question();
                    question.setProjectId(projectId);
                    question.setQuestionContent(questionDetail.toString());
                    question.setGroupId(groupId);
                    questionMapper.insert(question);
                }
            });

            Collections.sort(primeQuestions);
            Collections.sort(newQuestions);

            if (!(primeRules.equals(rules) && primeGroups.equals(newGroups) && primeQuestions.equals(newQuestions))){
                //删除application相关
                List<Integer> applicationIdList = applicationMapper.listApplicationIdsByProjectId(projectId);
                applicationService.delApplicationByProjectId(projectId);
                applicationService.delApplicationInfoByProjectId(projectId);
                if (!applicationIdList.isEmpty()){
                    applicationService.delApplicationCommentByApplicationId(applicationIdList);
                }

                //删除category相关
                List<CategoryParam1> categoryParamList = categoryMapper.getCategoryIdsByProjectId(projectId);
                List<Integer> categoryIdList = new ArrayList<>();
                for (CategoryParam1 categoryParam1 : categoryParamList){
                    categoryIdList.add(categoryParam1.getCategoryId());
                }
                categoryService.delCategoryByProjectId(projectId);
                if (!categoryIdList.isEmpty()){
                    categoryService.delCategoryInfoByCategoryId(categoryIdList);
                }

            }
            return ResultBody.success(projectService.getSingleProject(projectId));


        }catch (Exception e){
            logger.error("修改项目失败", e);
            return ResultBody.error("修改项目失败");
        }

    }



    @Operation(summary = "获取所有学院")
    @GetMapping("/user/departments")
    public ResultBody getColleges(){
        HttpRequest departmentR = HttpRequest.get("https://api.twt.edu.cn/api/department/all")
                .header("domain", "weipeiyang.twt.edu.cn")
                .header("ticket", "YmFuYW5hLjM3YjU5MDA2M2Q1OTM3MTY0MDVhMmM1YTM4MmIxMTMwYjI4YmY4YTc=")
                .header("Cookie", "JSESSIONID=824387D685F213C214C3E1A67F68DF64");

        JSONObject body = JSONUtil.parseObj(departmentR.execute().body(), JSONConfig.create().isIgnoreNullValue());
        Integer code  = body.getInt("code");
        String message = body.getStr("message");
        JSONArray result = JSONUtil.parseArray(body.getStr("result"));
        if (Objects.equals(body.getStr("message"), "成功")){
            return ResultBody.success(result);
        }
        return ResultBody.error(code.toString(), message, result);
    }

    @Operation(summary = "首页获取项目简介")
    @GetMapping("/user/project/all")
    public ResultBody getApplicationCategory(@RequestParam(required = false) Integer scale,
                                             @RequestParam(required = false) Integer status,
                                             @RequestParam(defaultValue = "1") Integer page,
                                             @RequestParam(defaultValue = "5") Integer pageSize){
        try {
            Page<Project> rowPage = new Page(page, pageSize);

            LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
            if (scale!=null){
                queryWrapper.eq(Project::getScale, scale);
            }
            if (status!=null){
                queryWrapper.eq(Project::getStatus, status);
            }else {
                queryWrapper.in(Project::getStatus, "0,2");
            }

            rowPage = projectMapper.selectPage(rowPage, queryWrapper);
            JSONObject re = JSONUtil.parseObj(rowPage);
            JSONArray records = new JSONArray();
            for (Project record : rowPage.getRecords()) {
                JSONObject t= JSONUtil.parseObj(record);
                t.putOpt("clubName", clubMapper.selectById(record.getClubId()).getName());
                t.putOpt("applicationNum", applicationMapper.getApplicationNum(record.getProjectId()));
                records.add(t);
            }
            re.putOpt("records", records);

            return ResultBody.success(re);

        }catch (Exception e){
            logger.error("获取项目分组信息失败", e);
            return ResultBody.error("获取项目分组信息失败");
        }
    }


    @Operation(summary = "获取社团的所有项目")
    @GetMapping("/staff/project/all")
    public ResultBody getClubProjects(@RequestHeader(JwtTokenUtils.TOKEN_HEADER) String token){
        Integer clubId = JwtTokenUtils.getClubHttp(token);
        JSONArray re = new JSONArray();
        for (Project project : projectMapper.listProjectByClubId(clubId)) {
            JSONObject t = JSONUtil.parseObj(project);
            t.putOpt("applicationNum", applicationMapper.getApplicationNum(project.getProjectId()));
            re.add(t);
        }
        return ResultBody.success(re);
    }

}
